home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
moredasm.arc
/
MOREDASM.NOT
Wrap
Text File
|
1987-01-26
|
20KB
|
513 lines
.lh 6
.cw 7
.mt 4
.mb 11
.pl 88
.op
APPLICATIONS: Using ASMGEN to disassemble MORE.COM
.he ASMGEN disassembly of MORE.COM Page #
The primary justification for writing programs in assembly
language is execution speed. Few would argue in favor of such
direct machine contact if there were easier ways to achieve the
performance improvements that are possible in comparison with
high-level programs like BASIC and Pascal.
The best way to achieve some level of literacy in assembly
language programming is to examine the programs written by
others. You can incorporate segments of their code in your
programs--or modify their programs to serve your own application.
Programs available in the public domain are ideal for this
purpose, since the sheer variety of programs raises the
likelihood that you will be able to find something close to what
you need. Unfortunately, they do not all come with the source
code.
For modifying programs for which you do not have the source
code, there is a disassembler available (again, in the public
domain) which you can use to reconstruct the basic program
structure. Named ASMGEN, it was written by Jack Gersbach and
J. Damke. (It turns out he is also the co-author of one of the
utilities packages now being marketed by IBM in its Personally
Developed Software series.) It available on Windmill, Thousand
Oaks, Simi, RIMS and most other public domain bulletin boards.
Look for version 2.01 or later.
We've chosen for an example the DOS filter MORE.COM. This
modest little program at 384 bytes is the smallest of the three filters
supplied with DOS. The other two, FIND.COM and SORT.COM, are
considerably more complex. MORE.COM provides in its small space
assembly language examples of the following operations (in rough
order of appearance in the program):
. Checking for DOS version number (2.00 or higher)
. Activating the required input and standard error devices
. Reading standard input into a buffer
. Using DOS file handles instead of File Control Blocks
. Using a System BIOS call for checking the width of the
current screen
. Managing a "shadow screen" to keep track of the cursor
. Checking input for end of file, enter, line feed,
backspace, tab and bell (beep) characters
. Correctly adjusting screen display for 8-space tab
. Wrapping the screen display if the line width exceeds
the screen width, whether it is 40 or 80 columns wide
. Pausing the display at each full screen, and waiting for a
keypress to proceed
To do this sort of disassembly operation properly, you need
a number of tools. A complete list comprises the following items:
. Disassembler: ASMGEN, V2.01 or later by Gersbach/Damke
(Public Domain)
. File compare: CMP10, V1.10 or later by Gersbach
(Public Domain)
. Concurrent text editor and utility: The Notepad and the
Calculator features of SideKick, V1.10B
from Borland International
. Main text editor: WordStar 3.3 in non-document mode
from MicroPro International
. Macro Assembler V1.00, from IBM/Microsoft
.cp 5
. Manuals:
Disk Operating System Reference Manual
Disk Operating System Technical Reference Manual
Technical Reference Personal Computer XT and
Portable Personal Computer
A reference manual on the Intel 8086/8088 instruction set
There is no point in attempting a disassembly of any size
without the DOS Technical Reference Manual. IBM and Microsoft
have moved all the required DOS function call information into a
separate manual starting with version 2.10. It is possible to
get by with the integrated DOS version 2.00 manual for the
function calls, but only as a last resort.
The hardware manual is another absolute requirement because
it is only in the System BIOS program listing that you will find
what the BIOS function calls mean. Even a program as nominally
trivial as MORE.COM uses a BIOS call to determine the width of
the current display screen. You will not be able to decode the
system interrupts without this manual.
The Macro Assembler is also required. Unlike CP/M, DOS
comes with no assembler. The only facility it has to assemble
programs is the "A" command in DEBUG, which will assemble into
memory the instructions you enter via the keyboard. This is on
the same approximate level as the Apple II monitor ROM assembler.
Since you must have the macro assembler, you might as well
use its macro facility. As you will see in the reconstructed
program listing that follows, all the BIOS and DOS function calls
have been recoded as macros. This allows you to remove yourself
from the requirement of remembering the purpose of each of the
hexadecimal functions, and shows more clearly the underlying flow
of the program in a language that you can define yourself that
makes most sense to you. This is how you can build up your DOS
function library.
Unfortunately, ASMGEN does not take its interpretation this
far; it is up to you to replace the INT 21 forms with the
appropriate macro call. Equally unfortunately, the DOS Technical
Reference Manual is mainly organized along the lines of the
hexadecimal function number, so you may find yourself referring
back to the macro definition to find the hex value of the call so
that you can locate its reference in the DOS manual. Sigh...
It would be difficult to imagine undertaking this sort of
exercise without SideKick. SideKick has a "notepad", which can
function as a concurrent text editor. SideKick has all the
features and command syntax of WordStar with the exception of
word wrap (not needed in the context of programming). It remains
resident so that by invoking it with the <shift><shift> keys
(holding down both <shift> keys simultaneously) you can edit the
.SEQ file required by ASMGEN to interpret the .COM file without
the delay of reloading and then unloading the main text editor.
A superior utility.
We use WordStar for word processing and text editing. There
are other word processors available. For this type of work,
where you are doing programming and debugging, you need windows.
We use SideKick for that purpose. You might also try XyWrite II
Plus (two windows), or FinalWord (multiple windows). Pmate also
has multiple edit buffers, but is thoroughly inscrutable.
Microsoft Word supports up to eight windows, but the entry/exit
overhead is too much and the internal format must be translated
to ASCII before it can be used. XyWrite takes a some setup time
as well, but it provides a facility whereby you can drop down to
DOS and back again very quickly.
Finally, the file compare program CMP10, also by Jack
Gersbach. This too is a public domain program. The absolute
first objective of a disassembly is the reconstruction of the
original file--byte for byte. The program listing that follows,
with all its macro definitions, will assemble, link, EXE2BIN and
REN into a .COM file that is absolutely identical to the source
.COM file. It is only after you have achieved this objective
that you should feel comfortable about modifying the
reconstructed .ASM file for your own purposes.
DOS provides a file compare program (COMP.COM), but
unfortunately if the files are of different lengths the utility
stops. This is of little use, since in most cases almost all
efforts at reassembly except for the very last will result in
.COM files of different lengths. CMP10 will compare files of
different lengths and show the differences as well--in hex and
ASCII format similar to a DEBUG display listing. Indispensable.
The reassembled and reconstituted source file for MORE.COM
follows. The source code shown here will generate a .COM file
that is absolutely identical, byte for byte, with the original
DOS 2.00 version from which it was constructed. It has been
checked against DOS Version 3.00. With the exception of a
slightly shorter buffer tail at the end of the program, DOS 3.00
is identical byte-for-byte to the DOS 2.00 program.
R. Zider
San Francisco, CA
11.18.84
Copyright 1984. All right reserved.
Released to the public domain for personal use only.
.pa
REASSEMBLY OF MORE.COM Exhibit 1
Listing of MOR.ASM
------------------
TITLE MOR 3-8-83 [11-17-84]
;
; Reassembly of IBM PC DOS 2.00 MORE.COM filter
;
; R. Zider Zider Brothers, San Francisco
;
;
.RADIX 16
BEL EQU 07H
BKSP EQU 08H
TAB EQU 09H
LF EQU 0AH
CR EQU 0DH
EOF EQU 1AH
;
; MACRO DEFINITIONS
;
;SYSTEM BIOS MACROS
;
VIDEO_BIOSCALL MACRO
;;Invoke System BIOS video I/O function call
;;On entry:
;;(AH) = Function number
;;See page 5-68ff Technical Reference Personal Computer XT and
;; Portable Personal Computer
INT 10H
ENDM
;
GET_CURRENT_VIDEO_STATE MACRO
;;Get screen width using a video BIOS call
;;On entry:
;;If (AH) = 15 (0FH), then function returns current video state
;;On exit:
;;"(AL) = Mode currently set (see AH=0 for explanation)"
;;"(AH) = Number of character columns on screen"
;;"(BH) = Current active display page"
;; Quoted from TRM page 5-69
MOV AH,0FH
VIDEO_BIOSCALL
ENDM
;
;
;DOS MACROS
;
DOS_EXIT MACRO
INT 20H
ENDM
;
DOSCALL MACRO
;;Standard DOS function call
;;On entry:
;;(AH) = Function call number
INT 21H
ENDM
CLEAR_KB_INPUT MACRO
;;Clear keyboard buffer, read char from std input device (keyboard)
;;Character returned in (AL)
MOV AH,0CH ;;Clear KB buffer (plus function in AL)
MOV AL,1H ;;Read char from KB function
DOSCALL
ENDM
;
.cp 5
DOS_DISPLAY_OUT MACRO
;;(DL) has the character to be displayed
MOV AH,2H
DOSCALL
ENDM
;
DOS_PRINT_STRING MACRO STRING_LABEL
;Output a "$"-terminated string
MOV DX,OFFSET STRING_LABEL
MOV AH,9H
DOSCALL
ENDM
;
GET_DOS_VERSION MACRO
;;Version number returned in two pieces:
;;(AL) = Major version number (as "02" or "03")
;;(AH) = Minor version number (as "00" or "01")
MOV AH,30H
DOSCALL
ENDM
;
CLOSE_FILE_HANDLE MACRO
;;On entry:
;;(BX) = File handle returned by "open" or "create"
;;On exit:
;;(AX) = Error codes (NONE if carry not set)
MOV AH,3EH
DOSCALL
ENDM
;
READ_FROM_FILE MACRO HANDLE, BYTES, BUFFER
;;Transfer bytes from a file into a buffer
;;On entry:
;;(BX) = File handle of source file
;;(CX) = Number of bytes to be read (max--may be less than this)
;;(DX) = Location of destination buffer
;;On exit:
;;(AX) = Number of bytes actually read; or else error code if carry set
MOV DX, OFFSET BUFFER
MOV CX, BYTES
MOV BX, HANDLE
MOV AH,3FH
DOSCALL
ENDM
;
DUP_FILE_HANDLE MACRO ;;HANDLE argument not yet implemented
;;This function duplicates a file handle
;;On entry:
;;(BX) = File handle to be duplicated
;;On exit:
;;(AX) = New file handle, referring to same file at same position
;; (or else error codes if carry set)
;; MOV BX, HANDLE ;;Need conditional assembly if arg missing
MOV AH,45H
DOSCALL
ENDM
;
; PROGRAM STARTS HERE
;
;
;INITIAL VALUES : CS:IP 0000:0100
; SS:SP 0000:FFFF
S0000 SEGMENT
ASSUME DS:S0000, SS:S0000 ,CS:S0000 ,ES:S0000
ORG $+0100H
START: GET_DOS_VERSION ;Check DOS version first
XCHG AH,AL ;Put major version in AH, minor in AL
CMP AX,200 ;Must be 2.00 or higher
JNB OK_VER_200
DOS_PRINT_STRING WRONG_DOS ;Nope..
DOS_EXIT ;..bye
.cp 5
OK_VER_200:
MOV BYTE PTR SCREEN_HEIGHT,19 ;Screen height 25 lines
GET_CURRENT_VIDEO_STATE ;Not sure of width, though--get it
MOV SCREEN_WIDTH,AH ;OK, save current width
DOS_PRINT_STRING CR_LF ;Flush screen with a CR-LF
XOR BX,BX ;Zero BX to get a duplicate..
DUP_FILE_HANDLE ;..file handle of std input (handle 0)
MOV BP,AX ;New file handle to BP
CLOSE_FILE_HANDLE ;Close handle 0 (std input)--use dup
MOV BX,2 ;Default handle 2 is std error output..
DUP_FILE_HANDLE ;..device--activate it
READ_STD_INPUT_INTO_BUFFER:
CLD ;Clear direction
; MOV DX,OFFSET BUFFER ;Destination buffer
; MOV CX,1000 ;Max of 1000H bytes (4KB)
; MOV BX,BP ;This has new std input file handle
READ_FROM_FILE BP 1000 BUFFER ;OK, read on..
;..and ignore any error return
OR AX,AX ;Check for non-zero bytes read
JNZ OK_READ ;"OK" if non-zero
EXIT: DOS_EXIT ;Empty std input file--bye
OK_READ:
MOV CX,AX ;Number of bytes read to CX
MOV SI,DX ;Buffer location to SI (now source)
LOAD_NEXT_BYTE:
LODSB ;Start processing bytes..
CMP AL,EOF ;..looking for an end-of-file (1AH)..
JZ EXIT ;..and exit if found
CMP AL,CR ;Check if it is a carriage return..
JNZ CK_LINEFEED ;..and if not, continue on with check
MOV BYTE PTR COLUMN_COUNT,1 ;CR, so reset to screen column 1 and..
JMP SHORT DISPLAY_OUT ;..output the CR to the screen
CK_LINEFEED:
CMP AL,LF ;Check if it is a line feed (OAH)..
JNZ CK_BKSPACE ;..and if not, go to next char check
INC BYTE PTR LINE_COUNT ;LF, so bump the line count and..
JMP SHORT DISPLAY_OUT ;..output the LF to the screen
CK_BKSPACE:
CMP AL,BKSP ;Check for backspace char (08H)..
JNZ CK_TAB ;..and if not, continue on to next
CMP BYTE PTR COLUMN_COUNT,1 ;Is backspace, check if at column 1..
JZ DISPLAY_OUT ;..and if so, just output the char
DEC BYTE PTR COLUMN_COUNT ;Not at column 1, so dec the column..
JMP SHORT DISPLAY_OUT ;..and output the backspace
CK_TAB: CMP AL,TAB ;Check for tab char (09H)..
JNZ CK_BEL ;..and if not, press on
MOV AH,COLUMN_COUNT ;Is tab, so get the current column..
ADD AH,7 ;..add 7 to it..
AND AH,0F8 ;..and mask for MOD 8..
INC AH ;..adding one..
MOV COLUMN_COUNT,AH ;..and make this the new column..
JMP SHORT DISPLAY_OUT ;..and output it to the display
CK_BEL: CMP AL,BEL ;Check for BEL (beep) char (07)
JZ DISPLAY_OUT ;Is a BEL, so let console handle it
INC BYTE PTR COLUMN_COUNT ;None of these, so bump the column..
MOV AH,COLUMN_COUNT ;..and check to see if we're at the
CMP AH,SCREEN_WIDTH ;..edge of the screen..
JBE DISPLAY_OUT ;..and if not, output the character
INC BYTE PTR LINE_COUNT ;At screen edge, so do a line wrap..
MOV BYTE PTR COLUMN_COUNT,1 ;..and bump the line and reset to col 1
DISPLAY_OUT:
MOV DL,AL ;Output the character..
DOS_DISPLAY_OUT ;..to the display via DOS call
MOV AH,LINE_COUNT ;Check the line count..
CMP AH,SCREEN_HEIGHT ;..against the screen height..
JB NEXT_BYTE ;..and continue if no overflow
DOS_PRINT_STRING MORE_LINE ;"--More--" message..
CLEAR_KB_INPUT ;..and pause for keyboard input
DOS_PRINT_STRING CR_LF ;OK, continue and clear More line..
MOV BYTE PTR COLUMN_COUNT,1 ;..reset screen pointers to Home..
MOV BYTE PTR LINE_COUNT,1 ;..at top left position (1,1)
DEC SI ;Back up one byte in buffer so that..
INC CX ;..the byte can be re-sent
NEXT_BYTE:
DEC CX ;One less byte to do, and..
JZ RD_NEXT_4K ;..if now zero, read another 4KB
JMP LOAD_NEXT_BYTE ;A computer's work is never done
RD_NEXT_4K:
JMP READ_STD_INPUT_INTO_BUFFER ;Heigh Ho, Heigh Ho...
SCREEN_HEIGHT EQU $
DB 18 ;24 lines, but gets overwritten
SCREEN_WIDTH EQU $
DB 50 ;Here, 80 columns wide (overwtritten)
LINE_COUNT EQU $
DB 1 ;Starts at 1
COLUMN_COUNT EQU $
DB 1,5 DUP(0) ;Starts at 1
MORE_LINE EQU $
DB CR,'-- More --$' ;Displayed on 25th line
WRONG_DOS EQU $
DB 'MORE: Incorrect DOS version'
CR_LF EQU $
DB CR,LF,'$'
BUFFER EQU $
DB 66 DUP(0) ;Read buffer only 66H bytes here
S0000 ENDS
;
END START
.pa
MORE.ASM Exhibit 2
Assembly and link to .COM file
------------------------------
This is what you will have to do to get a .COM file that you
can compare with the original MORE.COM program in DOS 2.00. The
following listing has been captured from the screen display with
FSPOOL.COM.
B>dir
Volume in drive B is PCDISASM
Directory of B:\mor
. <DIR> 11-04-84 2:17p
.. <DIR> 11-04-84 2:17p
M OBJ 536 11-17-84 7:24p
MOR ASM 2468 11-17-84 9:10a
M LST 15785 11-17-84 7:24p
M COM 384 11-17-84 7:21p
MOR OBJ 501 11-17-84 11:53a
MOR SEQ 617 11-17-84 9:07a
M EXE 1152 11-17-84 7:24p
MORE300 COM 320 8-14-84 8:00a
MORE COM 384 3-08-83 12:00p
M BIN 384 11-17-84 7:24p
M ASM 7168 11-17-84 4:39p
MOR COM 384 11-17-84 11:54a
N LST 15785 11-17-84 7:14p
NOTES 3525 11-17-84 7:04p
T PRN 512 11-17-84 7:44p
17 File(s) 181248 bytes free
B>masm m
Bad command or file name
B>a:ini
B>path=a:\
B>masm m
The IBM Personal Computer MACRO Assembler
Version 1.00 (C)Copyright IBM Corp 1981
Object filename [M.OBJ]:
Source listing [NUL.LST]: m.lst
Cross reference [NUL.CRF]:
Warning Severe
Errors Errors
0 0
B>link m
IBM Personal Computer Linker
Version 2.00 (C)Copyright IBM Corp 1981, 1982, 1983
Run File [M.EXE]:
List File [NUL.MAP]:
Libraries [.LIB]:
Warning: No STACK segment
There was 1 error detected.
B>exe2bin m
B>cmp10 m.bin more.com
Files are identical
.cp 15
B>dir m.*
Volume in drive B is PCDISASM
Directory of B:\mor
M OBJ 536 11-17-84 7:46p
M LST 15785 11-17-84 7:46p
M COM 384 11-17-84 7:21p
M EXE 1152 11-17-84 7:47p
M BIN 384 11-17-84 7:47p
M ASM 7168 11-17-84 4:39p
6 File(s) 180224 bytes free
B>fspool